#pragma once

#include <iostream>
#include <string>
#include <vector>
#include <sstream>

using namespace std;

class Parser
{
public:
  struct Pair;

private:
  istream &_input;
 
  inline string getNextLineWithoutComment()
  {
    string line;
    getline(_input,line);
  
    int found = line.find_first_of("#");

    if (found != string::npos) {
      line = line.substr(0,found);
    }

    return line; 
  }

  inline int convertToInt(const string &line)
  {
    return atoi(line.c_str());
  }

  inline string getNextValidLine()
  {
    string line;
    while ((line = getNextLineWithoutComment()).size() == 0);
    return line;
  }

  inline int readInt()
  {
    return convertToInt(getNextValidLine());   
  }

  inline Pair readIntPair()
  {
    string line = getNextValidLine();
    istringstream ss(line);
    int node1, node2;

    // FIXME: pode falhar quando o arquivo não estiver correto
    ss >> node1 >> node2; 

    // no trabalho os vértices começam em 1, mas eu implementei começando em 0.
    // por isso converto estes valores aqui
    return {node1-1, node2-1};
  }

  vector<Pair> _edges;

  int _nNodes;

public:
  struct Pair
  {
    int node1;
    int node2;
  };

  inline Parser(istream &input):
  _input(input),
  _nNodes(0)
  {
  }
  
  inline int getNumberOfNodes() const
  {
    return _nNodes;
  }
  
  inline const vector<Pair> &getEdges() const
  {
    return _edges;
  }

  inline Parser &parse()
  {
    _nNodes = readInt();
      
    int nEdges = readInt();

    for (int i = 0; i < nEdges; i++) {
      _edges.push_back(readIntPair());
    }

    return *this;
  }
};
